package miiteen.sys.shiro;

import miiteen.core.result.ResultMessage;
import miiteen.hr.user.beans.UserUserInfo;
import miiteen.hr.user.service.UserUserInfoService;
import miiteen.security.security.beans.SecurityAccount;
import miiteen.security.security.beans.SecurityPermission;
import miiteen.security.security.beans.SecurityUser;
import miiteen.security.security.service.SecurityAccountService;
import miiteen.security.security.service.SecurityObjRoleRelService;
import miiteen.security.security.service.SecurityUserService;
import miiteen.sys.login.bean.UserShiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义的Realm
 *
 * @author huangzhanhu
 * @version 创建时间：2014年6月12日 上午10:01:51
 */
public class ShiroDbRealm extends AuthorizingRealm {

    private SecurityAccountService securityAccountService;

    @Autowired
    public void setSecurityAccountService(SecurityAccountService securityAccountService) {
        this.securityAccountService = securityAccountService;
    }

    private SecurityObjRoleRelService securityObjRoleRelService;

    @Autowired
    public void setSecurityObjRoleRelService(SecurityObjRoleRelService securityObjRoleRelService) {
        this.securityObjRoleRelService = securityObjRoleRelService;
    }

    @Autowired
    private SecurityUserService securityUserService;

    public void setSecurityUserService(SecurityUserService securityUserService) {
        this.securityUserService = securityUserService;
    }

    @Autowired
    private UserUserInfoService userUserInfoService;

    public void setUserUserInfoService(UserUserInfoService userInfoService) {
        this.userUserInfoService = userInfoService;
    }

    /**
     * 获取身份验证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

        ResultMessage resultMessage = securityAccountService.verify(token.getUsername(),
                String.valueOf(token.getPassword()));

        if (resultMessage.getState() > 0) {
            SecurityAccount curAccount = (SecurityAccount) resultMessage.getData();
            UserShiro.ShiroUser sh = new UserShiro.ShiroUser();
            sh.setAccount(curAccount.getAccount());
            sh.setAccountId(curAccount.getId());
            //获取权限
            SecurityAccount roleAccount = securityAccountService.getAccount(curAccount.getId());
            sh.setRoleIds(roleAccount.getRoleIds());

            List<SecurityUser> securityUsers = securityUserService.findListByAccontId(curAccount.getId());
            for (SecurityUser securityUser : securityUsers) {
                switch (String.valueOf(securityUser.getAccountTypeId())) {
                    case "2001":
                        UserUserInfo userUserInfo = userUserInfoService.findFullInfoById(securityUser.getUserId());
                        if (userUserInfo != null) {
                            sh.addInfo(String.valueOf(securityUser.getAccountTypeId()), userUserInfo);
                        }
                        break;
                }
            }

            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(sh, curAccount.getPwd(),
                    getName());

            return simpleAuthenticationInfo;
        } else {
            throw new AuthenticationException();
        }
    }

    /**
     * 获取授权信息
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        UserShiro.ShiroUser shiroUser = (UserShiro.ShiroUser) principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        List<String> listPermissions = new ArrayList<String>();
        List<SecurityPermission> permissions = securityObjRoleRelService
                .getPerByUserId(String.valueOf(shiroUser.getAccountId()));
        for (SecurityPermission securityPermission : permissions) {
            listPermissions.add(
                    String.valueOf(securityPermission.getResourceCode() + ":" + securityPermission.getOperatCode()));
        }
        info.addStringPermissions(listPermissions);
        return info;
    }

    /**
     * 设定Password校验的Hash算法与迭代次数.
     */
    @PostConstruct
    public void initCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("MD5");

        setCredentialsMatcher(matcher);
    }
}
